using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Net.NetworkInformation;
using GHIElectronics.NETMF.Net;
using System.IO.Ports;


namespace FEZ_Cobra_Console_Application1
{
    /// <summary>
    /// Put this in main
    ///SerialPort Port4 = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
    ///PPP_start pps = new PPP_start(Port4);
    ///pps.connect();
    /// </summary>
    class PPP_start
    {
        static public SerialPort modem;
        static public bool network_is_read = false;

        public PPP_start(SerialPort sermodem)
        {
            //SerialPort modem = new SerialPort("COM2", 115200);
            modem = sermodem;
        }
        
        public void connect()
        {
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
            // Till this point TCP/IP stack is hooked previously Enabled interface (Ethernet by default)
            PPP.Enable(modem);

            modem.Handshake = Handshake.RequestToSend; // This is to avoid data loss during PPP communication.
            modem.Open();
            modem.ErrorReceived += new SerialErrorReceivedEventHandler(modem_ErrorReceived);
            NetworkInterface[] netif = NetworkInterface.GetAllNetworkInterfaces();


            Debug.Print("Dial-in using AT commands");
            ATcommander at = new ATcommander(modem);
            if (at.ClientConnectModem())
            {
                network_is_read = false;
                Debug.Print("Connect PPP");
                switch (PPP.Connect("WAP@CINGULARGPRS.COM", "CINGULAR1"))
                {
                    case PPP.ConnectionStatus.Authentication_Faild:
                        Debug.Print("Authentication_Failed");
                        break;
                    case PPP.ConnectionStatus.Connection_Faild:
                        Debug.Print("Connection_Failed");
                        break;
                    case PPP.ConnectionStatus.Connected:
                        // PPP setting will overload the first interface settings since only one interface is supported.
                        netif = NetworkInterface.GetAllNetworkInterfaces();
                        Debug.Print("PPP Network settings:");
                        Debug.Print("IP Address: " + netif[0].IPAddress);
                        Debug.Print("Subnet Mask: " + netif[0].SubnetMask);
                        Debug.Print("Default Getway: " + netif[0].GatewayAddress);
                        Debug.Print("DNS Server: " + netif[0].DnsAddresses[0]);
                        network_is_read = false;
                        break;
                    case PPP.ConnectionStatus.Disconnected:
                        Debug.Print("Disconnected");
                        break;

                }
            }
            else
            {
                Debug.Print("Terminal server is not responding");
            }
            if (network_is_read)
            {
                Debug.Print("Test DNS");
                try
                {
                    System.Net.IPHostEntry myIP = System.Net.Dns.GetHostEntry("www.ghielectronics.com");

                    if (myIP != null)
                    {
                        Debug.Print(myIP.HostName + ": " + myIP.AddressList[0].ToString());
                    }
                }
                catch
                {
                    Debug.Print("Faild to Get the host entry of the FQN from DNS server!");
                }

                Debug.Print("Disconnect PPP link.");
                PPP.Disconnect();

            }

            //Debug.Print("Disable PPP interface");
            //PPP.Disable();
            // At this point TCP/IP stack will reinitialized be hooked back to Ethernet or WiFi

            Thread.Sleep(Timeout.Infinite);

        }

        static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {

            if (e.IsAvailable)
            {
                if (PPP.IsLinkConnected)
                {
                    Debug.Print("PPP connection was established!");
                }
            }
            else
            {
                if (!PPP.IsLinkConnected)
                {
                    Debug.Print("PPP connection was dropped or disconnected!");
                    network_is_read = false;
                }
            }
        }

        static void modem_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            // Serial communication is loosing data
        }

    }
}
